import direct.directbase.DirectStart
from direct.actor import Actor
from direct.fsm import FSM
from pandac.PandaModules import *
from direct.interval.IntervalGlobal import *
from direct.task import Task
from direct.showbase.DirectObject import DirectObject
import math

environ = loader.loadModel("models/defaults/environment")
environ.reparentTo(render)

base.disableMouse()
base.camera.setPos(Point3(0, 130, 75))
base.camera.setHpr(0,-30,0)

class Rider (DirectObject):
    def __init__(self):
        
        self.actor = Actor.Actor("models/Animations/walking_anim", 
                         {"stand-walk":"models/Animations/stand2walkS",
                          "walk":"models/Animations/walking_anim", 
                          "runAT":"models/Animations/runningAT"})
    
        self.actor.setScale(.1,.1,.1)
        
        self.actor.reparentTo(render)
        self.actor.setPlayRate(.7, 'walk')
        self.stand2walkControl=self.actor.getAnimControl("stand-walk")
            
        self.mode="walk"
        
        self.keyMap = {"left":0, "right":0, "up":0, "down":0, "mouse-1":0, "mouse-3":0}

        
        self.accept("arrow_up", self.setKey, ["up", 1])
        self.accept("arrow_down", self.setKey, ["down", 1])
        self.accept("arrow_right", self.setKey, ["right", 1])
        self.accept("arrow_left", self.setKey, ["left", 1])
        self.accept("shift", self.setKey, ["shift", 1])
        self.accept("mouse1", self.setKey, ["mouse-1", 1])
        self.accept("mouse2", self.setKey, ["mouse-2", 1])
        self.accept("mouse3", self.setKey, ["mouse-3", 1])
        
        self.accept("a", self.switch)
#        self.accept("a", self.eh)
        
        self.accept("arrow_up-up", self.setKey, ["up", 0])
        self.accept("arrow_down-up", self.setKey, ["down", 0])
        self.accept("arrow_right-up", self.setKey, ["right", 0])
        self.accept("arrow_left-up", self.setKey, ["left", 0])
        self.accept("mouse1-up", self.setKey, ["mouse-1", 0])
        self.accept("mouse2-up", self.setKey, ["mouse-2", 0])
        self.accept("mouse3-up", self.setKey, ["mouse-3", 0])
        
        self.accept("b", self.stop)
        
        
        #self.walkControl=self.actor.getAnimControl("walk")
        #walking variables
        self.prevDegrees=0
        self.prevtime=0
        #self.counter=0
        self.prevPos=(0,0,0)
        self.transitionEnding=True
        self.transitionEnding2=False
        #taskMgr.add(self.Walk,"character walking")
        
        
        self.step="R"
        self.state="stand"
        self.frame=0
        
        self.actor.pose("stand-walk", 0)
        
        self.speed=0/30
        
        self.prevX=self.actor.getX()
        self.prevY=self.actor.getY()
        self.prevZ=self.actor.getZ()
        
        self.prevMouseX=0
        self.prevMouseY=0
        
        self.actor.pose("runAT", 1)
        taskMgr.add(self.RunAT, "running with ATs")
        
        
        #base.camera.setPos(Point3(0, 1000, 500))
        #base.camera.setP(-20)

        #self.mode="walk"
    
#    def eh(self):
#        print "ake"
#        self.actor.play('walk')
#        taskMgr.add(self.play,"kfjahdf")
    def test(self):
	        print "passed test"
    def setKey(self, key, value):
        self.keyMap[key] = value
#    def play(self, task):
#        if self.walkControl.isPlaying()==False:
#            print task.time
#            return Task.done
#        return Task.cont
    def stop (self):
        self.actor.stop()
        self.state="walk"
    def switch (self):
        if self.mode=="walk":
            self.mode="AT"
            self.actor.pose("runAT", 1)
            taskMgr.remove('character walking')
            taskMgr.add(self.RunAT, "running with ATs")
        elif self.mode=="AT":
            self.mode=="walk"
    def RunAT(self, task):
        #variable controlling speed and distance
            
        #
#        if base.mouseWatcherNode.hasMouse():
#            x=base.mouseWatcherNode.getMouseX()
#            y=base.mouseWatcherNode.getMouseY()
        if self.keyMap["mouse-1"]!=0 and self.keyMap["mouse-3"]==0 and self.state=="stand":
            print "blah", self.actor.getCurrentFrame("runAT")
            if self.step=="R":
                self.actor.setSx(self.actor, -1)
                self.step="L"
            self.actor.play("runAT", fromFrame=2, toFrame=41)
            self.frame=task.frame
            base.win.movePointer(0, base.win.getProperties().getXSize()/2, base.win.getProperties().getYSize()/2)
            self.prevMouseX=0
            self.prevMouseY=0                                                                                                                                                                                                                                                                                                                                        
            self.speed=self.speed+(.5/30)
            self.state="stand-runL1"
        elif self.state=="stand-runL1":
            if base.mouseWatcherNode.getMouseX()>.9:
                if (self.actor.getR()+(self.prevMouseX-.9)/3*45)>=-30:
                    self.actor.setR(self.actor.getR()+(self.prevMouseX-.9)/3*45)
                else:
                    self.actor.setR(-30)
                base.win.movePointer(0, base.win.getProperties().getXSize()*.05, base.win.getProperties().getYSize()*((-(base.mouseWatcherNode.getMouseY())+1)/2))
                self.prevMouseX=-.9
            elif base.mouseWatcherNode.getMouseX()<-.9:
                if (self.actor.getR()+(self.prevMouseX-(-.9))/3*45)<=30:
                    self.actor.setR(self.actor.getR()+(self.prevMouseX-(-.9))/3*45)
                else:
                    self.actor.setR(30)
                base.win.movePointer(0, base.win.getProperties().getXSize()*.95, base.win.getProperties().getYSize()*((-(base.mouseWatcherNode.getMouseY())+1)/2))            
                self.prevMouseX=.9
            elif self.prevMouseX!=base.mouseWatcherNode.getMouseX():
                if (self.actor.getR()+(self.prevMouseX-base.mouseWatcherNode.getMouseX())/3*45)>=-30 and (self.actor.getR()+(self.prevMouseX-base.mouseWatcherNode.getMouseX())/3*45)<=30:
                    self.actor.setR(self.actor.getR()+(self.prevMouseX-base.mouseWatcherNode.getMouseX())/3*45)
                elif (self.actor.getR()+(self.prevMouseX-base.mouseWatcherNode.getMouseX())/3*45)<-30:
                    self.actor.setR(-30)
                elif (self.actor.getR()+(self.prevMouseX-base.mouseWatcherNode.getMouseX())/3*45)>30:
                    self.actor.setR(30)
                self.prevMouseX=base.mouseWatcherNode.getMouseX()
            self.actor.setH(self.actor.getH()+(self.actor.getR()/60))
            self.speed=self.speed+(.5/30)
            if self.frame+39<=task.frame:
                self.state="runL1"
        if self.state=="runL1" and self.keyMap["mouse-1"]!=0:
            if base.mouseWatcherNode.getMouseX()>.9:
                if (self.actor.getR()+(self.prevMouseX-.9)/3*45)>=-30:
                    self.actor.setR(self.actor.getR()+(self.prevMouseX-.9)/3*45)
                else:
                    self.actor.setR(-30)
                base.win.movePointer(0, base.win.getProperties().getXSize()*.05, base.win.getProperties().getYSize()*((-(base.mouseWatcherNode.getMouseY())+1)/2))
                self.prevMouseX=-.9
            elif base.mouseWatcherNode.getMouseX()<-.9:
                if (self.actor.getR()+(self.prevMouseX-(-.9))/3*45)<=30:
                    self.actor.setR(self.actor.getR()+(self.prevMouseX-(-.9))/3*45)
                else:
                    self.actor.setR(30)
                base.win.movePointer(0, base.win.getProperties().getXSize()*.95, base.win.getProperties().getYSize()*((-(base.mouseWatcherNode.getMouseY())+1)/2))            
                self.prevMouseX=.9
            elif self.prevMouseX!=base.mouseWatcherNode.getMouseX():
                if (self.actor.getR()+(self.prevMouseX-base.mouseWatcherNode.getMouseX())/3*45)>=-30 and (self.actor.getR()+(self.prevMouseX-base.mouseWatcherNode.getMouseX())/3*45)<=30:
                    self.actor.setR(self.actor.getR()+(self.prevMouseX-base.mouseWatcherNode.getMouseX())/3*45)
                elif (self.actor.getR()+(self.prevMouseX-base.mouseWatcherNode.getMouseX())/3*45)<-30:
                    self.actor.setR(-30)
                elif (self.actor.getR()+(self.prevMouseX-base.mouseWatcherNode.getMouseX())/3*45)>30:
                    self.actor.setR(30)
                self.prevMouseX=base.mouseWatcherNode.getMouseX()
            if base.mouseWatcherNode.getMouseY()>.9:
                if (self.actor.getP()+(.9-self.prevMouseY)*45)<=45:
                    self.actor.setP(self.actor.getP()+(.9-self.prevMouseY)*45)
                else:
                    self.actor.setP(45)
                base.win.movePointer(0, base.win.getProperties().getXSize()*((base.mouseWatcherNode.getMouseX()+1)/2), base.win.getProperties().getYSize()*.95)
                self.prevMouseY=-.9
            elif base.mouseWatcherNode.getMouseY()<-.9:
                if (self.actor.getP()+(-.9-self.prevMouseY)*45)>=0:
                    self.actor.setP(self.actor.getP()+(-.9-self.prevMouseY)*45)
                else:
                    self.actor.setP(0)
                base.win.movePointer(0, base.win.getProperties().getXSize()*((base.mouseWatcherNode.getMouseX()+1)/2), base.win.getProperties().getYSize()*.05)
                self.prevMouseY=.9  
            elif self.prevMouseY!=base.mouseWatcherNode.getMouseY():
                if (self.actor.getP()+(base.mouseWatcherNode.getMouseY()-self.prevMouseY)*45)<=45 and (self.actor.getP()+(base.mouseWatcherNode.getMouseY()-self.prevMouseY)*45)>=0:
                    self.actor.setP(self.actor.getP()+(base.mouseWatcherNode.getMouseY()-self.prevMouseY)*45)
                elif (self.actor.getP()+(base.mouseWatcherNode.getMouseY()-self.prevMouseY)*45)>45:
                    self.actor.setP(45)
                elif (self.actor.getP()+(base.mouseWatcherNode.getMouseY()-self.prevMouseY)*45)<0:
                    self.actor.setP(0)
                self.prevMouseY=base.mouseWatcherNode.getMouseY()
            self.actor.setH(self.actor.getH()+(self.actor.getR()/60))
            if self.speed>=0 and self.speed<=90/30:
                self.speed=self.speed+((self.actor.getP()-10)/7)/30
            elif self.speed+((self.actor.getP()-10)/7)/30<0:
                self.speed=0
                print "swag"
            elif self.speed+((self.actor.getP()-10)/7)/30>90/30:
                self.speed=90/30
                
            

            if self.actor.getCurrentFrame("runAT")!=42:
                    self.actor.pose("runAT", 42)
        if self.state=="runL1" and self.keyMap["mouse-1"]==0:
            self.actor.play("runAT", fromFrame=43, toFrame=74)
            self.frame=task.frame
            self.state="runL1-runL2"
        if self.state=="runL1-runL2":
            if self.frame+31<=task.frame:
                #print "blah3", self.actor.getCurrentFrame("runAT")
                self.state="runL2"                  
        if self.state=="runL2":
            pass
        '''
        #need new animation for leg switch
        
        if self.state=="runL2" and self.keyMap["mouse-3"]!=0:
            self.actor.play("runAT")            
            self.state="runL2-runR1"
        if self.state=="runL2-runR1":
            if self.frame+42<=task.frame:
            	self.state=runR1
        '''

            
        if self.keyMap["mouse-3"]!=0 and self.keyMap["mouse-1"]==0 and self.state=="stand":
            print "blah2"
            if self.step=="L":
                self.actor.setSx(self.actor, -1)
                self.step="R"
            self.actor.play("runAT", fromFrame=2, toFrame=41)
            self.frame=task.frame
            self.speed=self.speed+30/30
            self.state="stand-runR1"
        if self.state=="stand-runR1":
            if self.frame+39<=task.frame:
                if self.keyMap["mouse-3"]!=0:
                    self.state="runR1"
                else:
                    self.state="runR1-runR2"  
        if self.state=="runR1" and self.keyMap["mouse-3"]!=0:
            self.actor.pose("runAT", 42)
            #insert ability to read mouse's y movement and adjust pitch accordingly
            #same as above with y and heading
            #change speed with mouse movements
        if self.state=="runR1" and self.keyMap["mouse-3"]==0:
            self.actor.play("runAT", fromFrame=43, toFrame=74)
            self.frame=task.frame
            self.state="runR1-runR2"
        if self.state=="runR1-runR2":
            if self.frame+31<=task.frame:
                self.state="runR2"                  
        if self.state=="runR2":
            pass
        '''
        #need new animation for leg switch
        
        if self.state=="runR2" and self.keyMap["mouse-1"]!=0:
            self.actor.play("runAT")            
            self.state="runR2-runL1"
        if self.state=="runR2-runL1":
            if self.frame+42<=task.frame:
                self.state=runL1
        '''
        
        #if task.frame%10==0:
            #print self.actor.getPos()
##        if round(task.time)%4==0:
##            base.camera.posInterval(.7,Point3(self.actor.getX()-(130*math.sin((self.actor.getH()*math.pi/180))),self.actor.getY()+(130*math.cos((self.actor.getH()*math.pi/180))), base.camera.getZ())).start()
##            self.prevX=self.actor.getX()
##            self.prevY=self.actor.getY()
        base.camera.setPos(self.actor.getX()-(130*math.sin((self.actor.getH()*math.pi/180))),
                           self.actor.getY()+(130*math.cos((self.actor.getH()*math.pi/180))),
                           base.camera.getZ())
        base.camera.lookAt(self.actor)
        self.move()

#LEFT OFF POINT: factor in acceleration. group ifs so that they make sense and turn some to elifs. work on mouse movement. set the frames in code to match the frames of the anim. 
#

        #self.actor.setPos(self.actor.getX()+x, self.actor.getY()-y, self.actor.getZ())
            
        return Task.cont
    def move(self):
        if self.speed==0:
            print "duuude"
        x=self.speed*math.sin((self.actor.getH()*math.pi/180))
        y=self.speed*math.cos((self.actor.getH()*math.pi/180))
        sun=self.actor.getX()+x
        self.actor.setPos(self.actor.getX()+x, self.actor.getY()-y, self.actor.getZ())
        if self.actor.getY()-y==sun:
            print "car"
    def mouseBorderX(self):
        if base.mouseWatcherNode.getMouseX()>=.9:
            self.actor.setR(self.actor.getR()+(.9-self.prevMouseX)/3*45)
            base.win.movePointer(0, base.win.getProperties().getXSize()*.05, base.win.getProperties().getYSize()*((-(base.mouseWatcherNode.getMouseY())+1)/2))
            self.prevMouseX=-.9
        elif base.mouseWatcherNode.getMouseX()<=-.9:
            self.actor.setR(self.actor.getR()+(-.9-self.prevMouseX)/3*45)
            base.win.movePointer(0, base.win.getProperties().getXSize()*.95, base.win.getProperties().getYSize()*((-(base.mouseWatcherNode.getMouseY())+1)/2))            
            self.prevMouseX=.9
    def mouseBorderY(self):
        if base.mouseWatcherNode.getMouseY()>=.9:
            self.actor.setP(self.actor.getP()+(.9-self.prevMouseY)/3*45)
            base.win.movePointer(0, base.win.getProperties().getXSize()*((base.mouseWatcherNode.getMouseX()+1)/2), base.win.getProperties().getYSize()*.95)
            self.prevMouseY=-.9
        elif base.mouseWatcherNode.getMouseY()<=-.9:
            self.actor.setP(self.actor.getP()+(-.9-self.prevMouseY)/3*45)
            base.win.movePointer(0, base.win.getProperties().getXSize()*((base.mouseWatcherNode.getMouseX()+1)/2), base.win.getProperties().getYSize()*.05)
            self.prevMouseY=.9                           
    def Walk(self, task):
        cameraPosInterval=base.camera.posInterval(1.0,base.camera.getPos())
        x=0 #movement on x axis
        y=0 #movement on y
        degrees=self.prevDegrees #direction facing
        
        
        move=35/30 #distance per step
            
        xBoundary=34
        yBoundary=34
        if self.keyMap["left"]!=0:
            x=-move
            degrees=270
        elif self.keyMap["down"]!=0:
            y=-move
            degrees=0
        elif self.keyMap["up"]!=0:
            y=move
            degrees=180
        elif self.keyMap["right"]!=0:
            x=move
            degrees=90
        if (base.camera.getX()+xBoundary)<(self.actor.getX()+x) or (base.camera.getX()-xBoundary)>(self.actor.getX()+x) or (base.camera.getY()-yBoundary)>(self.actor.getY()+y) or (base.camera.getY()+yBoundary)<(self.actor.getY()+y):
            base.camera.posInterval(.5,Point3(self.actor.getX()+x,self.actor.getY()+y, base.camera.getZ())).start()
        #makes camera follow bob
        
        self.actor.setH(degrees)
        self.prevDegrees=degrees
        if (self.keyMap["right"]!=0 or self.keyMap["left"]!=0 or self.keyMap["up"]!=0 or self.keyMap["down"]!=0) and self.stand2walkControl.isPlaying()==False:
            self.actor.play("stand2walk", fromFrame=1, toFrame=7)
            self.transitionEnding=True
        #moves from standing to walk
            
        if (self.keyMap["right"]!=0 or self.keyMap["left"]!=0 or self.keyMap["up"]!=0 or self.keyMap["down"]!=0) and self.transitionEnding:
            self.actor.loop("stand2walk", fromFrame=8, toFrame=37)
            self.transitionEnding=False
            self.transitionEnding2=True
        #looping the walking while a button is being held
        
#        if self.actor.getCurrentFrame("walk")==30:#figure out last frame. may not be 30
#            self.transitionEnding=True
        if self.keyMap["right"]==0 and self.keyMap["left"]==0 and self.keyMap["up"]==0 and self.keyMap["down"]==0 and self.transitionEnding2:
            #self.actor.play("stand2walk", fromFrame=38, toFrame=44)
            self.actor.pose("stand2walk", 0)
            self.transitionEnding2=False
        #transition from walking to standing
            #current=self.actor.getCurrentFrame("walk")
            #self.actor.play("walk", fromFrame=current)

        self.actor.setPos(self.actor.getX()+x,self.actor.getY()+y,self.actor.getZ())
        self.prevtime=task.time
#        if self.prevPos!=self.actor.getPos():
#            self.counter+=1
#            print self.counter, self.actor.getPos()
#        self.prevPos=self.actor.getPos()
        return Task.cont
    #def ride (self):
        
Rider()
run()
